package com.tozed.android.launcher.simpleui;

import java.util.HashMap;

import com.tozed.android.launcher.LauncherApplication;
import com.tozed.android.launcher.LauncherModel;
import com.tozed.android.launcher.R;
import com.tozed.android.launcher.Utilities;

import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.drawable.Drawable;

public class SimpleIconCache
{
	private static final String TAG = "SimpleLauncher.IconCache";
	private static final int INITIAL_ICON_CACHE_CAPACITY = 50;
	private static final Canvas sCanvas = new Canvas();
	private final HashMap<ComponentName, CacheEntry> mCache = 
			new HashMap<ComponentName, CacheEntry>(INITIAL_ICON_CACHE_CAPACITY);
	private final LauncherApplication mContext;
	private final Bitmap mDefaultIcon;
	private int mIconDpi;
	private final Drawable mNeedAddedIcon;
	private final PackageManager mPackageManager;

	static{
		sCanvas.setDrawFilter(new PaintFlagsDrawFilter(4, 2));
	}

	public SimpleIconCache(LauncherApplication app)
	{
		mContext = app;
		mPackageManager = app.getPackageManager();
		mIconDpi = app.getResources().getDisplayMetrics().densityDpi;
		mDefaultIcon = makeDefaultIcon();
		
		mNeedAddedIcon = mContext.getResources().getDrawable(R.drawable.bg_text);
	}
	
	private CacheEntry cacheLocked(ComponentName componentName, ResolveInfo resolveInfo, 
			HashMap<Object, CharSequence> labelCache)
	{
	    CacheEntry entry = (CacheEntry)mCache.get(componentName);
	    
	    if (entry == null)
	    {
	    	entry = new CacheEntry();
	      mCache.put(componentName, entry);
	      
	      ComponentName key = SimpleLauncherModel.getComponentNameFromResolveInfo(resolveInfo);
	      
	      if (labelCache != null && labelCache.containsKey(key)){
	    	  //if (SimpleFolder.CLASS_NAME.equals(key.getClassName()));
	    	  entry.title = labelCache.get(key).toString();
	      }else{
	    	  entry.title = resolveInfo.loadLabel(mPackageManager).toString();
              if (labelCache != null) {
                  labelCache.put(key, entry.title);
              }
	      }
	      
	      if (entry.title == null) {
              entry.title = resolveInfo.activityInfo.name;
          }
	    }
	    
	    entry.icon = SimpleUtilities.createIconBitmap(getFullResIcon(resolveInfo), mContext);
	    return entry;
	}
	
	public void flush()
	{
		synchronized (mCache){
			mCache.clear();
		}
	}
	
	public HashMap<ComponentName, Bitmap> getAllIcons()
	{
	    synchronized (mCache) {
            HashMap<ComponentName,Bitmap> set = new HashMap<ComponentName,Bitmap>();
            for (ComponentName cn : mCache.keySet()) {
                final CacheEntry e = mCache.get(cn);
                set.put(cn, e.icon);
            }
            return set;
        }
	}

	private Bitmap makeDefaultIcon(){
		Drawable drawable = getFullResDefaultActivityIcon();
		Bitmap bmp = Bitmap.createBitmap(Math.max(drawable.getIntrinsicWidth(), 1),
				Math.max(drawable.getIntrinsicHeight(), 1),
				Bitmap.Config.ARGB_8888);
		
		Canvas canvas = new Canvas(bmp);
		drawable.setBounds(0, 0, bmp.getWidth(), bmp.getHeight());
		drawable.draw(canvas);
		canvas.setBitmap(null);
		return bmp;
	}
	
	// 获得默认图标(取系统默认的)
	public Drawable getFullResDefaultActivityIcon(){
		return getFullResIcon(Resources.getSystem(), android.R.mipmap.sym_def_app_icon);
	}
	
	public Drawable getFullResIcon(ActivityInfo activityInfo)
	{
	    try
	    {
	      Resources res = mPackageManager.getResourcesForApplication(activityInfo.applicationInfo);
	      if (res != null)
	      {
	        int iconRes = activityInfo.getIconResource();
	        if (iconRes != 0)
	           return getFullResIcon(res, iconRes);
	      }
	    }catch (PackageManager.NameNotFoundException e){
	    	
	    }
	    
	    return getFullResDefaultActivityIcon();
	}

	public Drawable getFullResIcon(ResolveInfo resolveInfo){
		return getFullResIcon(resolveInfo.activityInfo);
	}

	public Drawable getFullResIcon(Resources resources, int id)
	{
	    try
	    {
	      Drawable drawable = resources.getDrawableForDensity(id, mIconDpi);
	      if (drawable != null) return drawable;
	    }catch (Resources.NotFoundException e){   
	    }
	    
	    return getFullResDefaultActivityIcon();
	}
	
	public Drawable getNeedAddedIcon()
	{
	    return mNeedAddedIcon;
	}
	
	public Bitmap getIcon(Intent intent){
		synchronized (mCache){
			ResolveInfo resolveInfo = mPackageManager.resolveActivity(intent, 0);
			ComponentName componentName = intent.getComponent();
			if ((resolveInfo == null) || (componentName == null))
				return mDefaultIcon;
			
			Bitmap bmp = cacheLocked(componentName, resolveInfo, null).icon;
			return bmp;
		}
	}
	
	public boolean isDefaultIcon(Bitmap bmp){
		return mDefaultIcon == bmp;
	}
	
	public CharSequence getTitle(Intent paramIntent)
	{
	    synchronized (this.mCache)
	    {
	      ResolveInfo localResolveInfo = this.mPackageManager.resolveActivity(paramIntent, 0);
	      ComponentName localComponentName = paramIntent.getComponent();
	      if ((localResolveInfo == null) || (localComponentName == null))
	        return "";
	      
	      String str = cacheLocked(localComponentName, localResolveInfo, null).title;
	      return str;
	    }
	}

	public void getTitleAndIcon(SimpleApplicationInfo appInfo, ResolveInfo resolveInfo, HashMap<Object, CharSequence> map)
	{
	    synchronized (this.mCache){
	      CacheEntry localCacheEntry = cacheLocked(appInfo.componentName, resolveInfo, map);
	      appInfo.title = localCacheEntry.title;
	      appInfo.mIcon = localCacheEntry.icon;
	    }
	}

	public void remove(ComponentName componentName){
		synchronized (mCache){
			mCache.remove(componentName);
			return;
		}
	}
	
	private static class CacheEntry{
		public Bitmap icon;
		public String title;
	}
}
